<template>
  <div class="bg-white rounded border border-gray-200 relative flex flex-col">
    <!--    <div class="px-6 pt-6 pb-5 font-bold border-b border-gray-200">-->
    <!--      <span class="card-title">Upload</span>-->
    <!--      <i class="fas fa-upload float-right text-green-400 text-2xl"></i>-->
    <!--    </div>-->
    <div class="p-6">
      <!-- Upload Dropbox -->
      <div
          :class="{ 'bg-green-400 border-green-400 border-solid': is_dragover }"
          @drag.prevent.stop=""
          @dragstart.prevent.stop=""
          @dragend.prevent.stop="is_dragover = false"
          @dragover.prevent.stop="is_dragover = true"
          @dragenter.prevent.stop="is_dragover = true"
          @dragleave.prevent.stop="is_dragover = false"
          @drop.prevent.stop="upload"
          class="w-full px-10 py-20 rounded text-center
          cursor-pointer border border-dashed border-gray-400
          text-gray-400 transition duration-500 hover:text-white
          hover:bg-green-400 hover:border-green-400 hover:border-solid"
      >
        <h5>Drop your files here</h5>
      </div>
      <hr class="my-6"/>
      <!-- Progess Bars -->
      <div class="mb-4" v-for="upload in uploads" :key="upload.name">
        <!-- File Name -->
        <div class="font-bold text-sm" :class="upload.text_class">
          <i :class="upload.icon"></i>{{ upload.name }}
        </div>
        <div class="flex h-4 overflow-hidden bg-gray-200 rounded">
          <!-- Inner Progress Bar -->
          <div
              class="transition-all progress-bar"
              :class="upload.variant"
              :style="{ width: upload.current_progress + '%' }"
          ></div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import axios from 'axios'

export default {
  name: 'MalUpload',
  props: {
    onUpload: {
      type: Function
    },
    authorization: {
      type: String
    },
    action: { // 上传目标地址
      type: String,
      // 如果用户传了upload方法,就不需要再使用内置的上传了
      // required: true
    },
    onSuccess: {
      type: Function
    },
    onError: {
      type: Function
    }
  },
  data() {
    return {
      // 拖动到upload组件上方时
      is_dragover: false,
      // 上传中的文件
      uploads: [],
    }
  },
  methods: {
    upload($event) {
      this.is_dragover = false
      const files = [...$event.dataTransfer.files]
      files.forEach(file => {
        // if (file.type != 'audio/mpeg') {
        //   return
        // }
        // 保存到队列
        // 一个元素表示一个进度条数据
        const uploadIndex = // 当前上传的文件的索引
            // 一个元素表示一个进度条数据
            this.uploads.push({
              current_progress: 0,
              name: file.name,
              variant: 'bg-blue-400',
              icon: 'fas fa-spinner fa-spin',
              text_class: ''
            }) - 1
        // 上传逻辑应该用户传
        if (this.$props.onUpload) {
          // 传递当前文件,  (后两个用于控制进度条样式) 当前文件队列, 当前文件索引
          this.$props.onUpload(file, this.uploads, uploadIndex)
        } else {
          window.axiosPromiseArr = []
          // 拦截器, 防止页面跳转后依然继续
          axios.interceptors.request.use(config => {
            //发起请求时保存页面所有请求
            config.cancelToken = new axios.CancelToken(cancel => {
              window.axiosPromiseArr.push({cancel})
            });
            return config
          })

          axios.interceptors.response.use(res => {
            //事件处理
          }, error => {
            if (axios.isCancel(error)) {
              // 为了终结promise链 (实际请求不会走到.catch(rej=>{}),这样就不会触发错误提示之类的)
              return new Promise(() => {
              });
            } else {
              return Promise.reject(error)
            }
          })

          axios({
            method: 'post',
            url: this.action,
            data: {
              file: file
            },
            headers: {
              'Content-Type': 'multipart/form-data',
              // 用户可以自己传token
              'Authorization': localStorage.getItem("authorization") || this.$props.authorization
            },
            onUploadProgress: (progressEvent) => {
              // if (progressEvent.lengthComputable) {
              let complete
              this.uploads[uploadIndex].current_progress = complete =
                  (progressEvent.loaded / progressEvent.total * 100).toFixed(1)
              // (((progressEvent.loaded / progressEvent.total) * 100) | 0)
              if (complete >= 100) {
                // 上传成功
                this.uploads[uploadIndex].variant = "bg-green-400";
                this.uploads[uploadIndex].icon = "fas fa-check";
                this.uploads[uploadIndex].text_class = "text-green-400";
              }
            }
            // }
          })
              .catch((error) => {
                // aop 用户传入处理方法
                if (this.$props.onError) this.$props.onError(error)
                this.uploads[uploadIndex].variant = "bg-red-400";
                this.uploads[uploadIndex].icon = "fas fa-times";
                this.uploads[uploadIndex].text_class = "text-red-400";
                console.log(error);
              })
              // 监听函数才能拿到this.$props
              .then((response) => {
                if (this.$props.onSuccess) this.$props.onSuccess(response)
              })
        }
      })
    }
  },
  beforeUnmount() {
    window.axiosPromiseArr.forEach((ele, index) => {
      ele.cancel() // 路由跳转之前，终止上一个页面正在请求的内容
      // 清空请求的参数
      delete window.axiosPromiseArr[index]
    })
  }
}
</script>